<?php
namespace Yls;

class Client {
    
    private $_url; // API服务地址
    private $_id; // 分配的ID
    private $_key; // 分配的私钥
    private $_version; // API 版本号
    
    private static $_instance;
    
    public function __construct($url, $id, $key, $version) {
        if(!(self::$_instance instanceof self)) {
            $this->_url = $url;
            $this->_id = $id;
            $this->_key = $key;
            $this->_version = $version;
        }
        return self::$_instance;
    }
    
    /**
     * 发起查询
     * @return mixed 查询结果
     * @throws \Exception
     */
    public function Query() {
        $wait = true;
        if(1 == func_num_args()) {
            $query = func_get_arg(0);
            if(isset($query['wait'])) $wait = $query['wait']; // 是否等待返回结果
            $query = [$query];
        } else {
            $query = [];
            foreach(func_get_args() as $arg) {
                is_array($arg) && array_push($query, $arg);
            }
        }
        $auth = ['ID' => $this->_id, 'KEY' => $this->MakeKey(), 'VERSION' => $this->_version];
        
        if(preg_match('/^https?:/', $this->_url)) {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $this->_url);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            /**
             * 传输大数据时需加“Expect: ”声明头
             * @see http://www.php.net/manual/zh/function.curl-setopt.php#82418
             */
            curl_setopt($ch, CURLOPT_HTTPHEADER, ['Expect: ']);
            curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
            $header = [];
            array_walk($auth, function($item, $key) use (&$header) {
                $header[] = 'YLS-'.$key.': '.$item;
            });
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header); // 验证信息放到请求头部分
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_TIMEOUT, $wait ? 30 : 1);
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($query));
            $response = curl_exec($ch);
            curl_close($ch);
            if(!$wait) return;
        } else {
            $Yls = include $this->_url;
            $response = $Yls($auth, $query);
        }
        
        if(is_numeric($response)) throw new \Exception($response, E_USER_ERROR); // 为数值时调用json_encode()方法不会报错
        $result = json_decode($response);
        if($result) {
            if(isset($result->status) && isset($result->data)) {
                if($result->status) return $result->data;
                else die($result->data);
            } else die($response);
        } else {
            die($response);
        }
    }
    
    /**
     * 生成加密验证key
     * @return string
     */
    private function MakeKey() {
        $time = time();
        return $key = sha1($this->_id.'YLS'.$this->_key.'YLS'.$time).'.'.$time;
    }
}